from abc import ABC, abstractmethod
from typing import Dict, Any, Optional
from enum import Enum
from decimal import Decimal

class PaymentProvider(str, Enum):
    """支付提供商"""
    WECHAT_PAY = "wechat_pay"
    ALIPAY = "alipay"
    STRIPE = "stripe"

class PaymentMethod(str, Enum):
    """支付方式"""
    APP = "app"           # 移动应用支付
    JSAPI = "jsapi"       # 公众号支付/小程序支付
    H5 = "h5"             # H5支付
    NATIVE = "native"     # 扫码支付
    MICROPAY = "micropay" # 刷卡支付

class OrderStatus(str, Enum):
    """订单状态"""
    PENDING = "pending"       # 待支付
    PAID = "paid"            # 已支付
    CANCELLED = "cancelled"   # 已取消
    REFUNDED = "refunded"    # 已退款
    FAILED = "failed"        # 支付失败

class PaymentRequest:
    """支付请求"""
    def __init__(
        self,
        order_id: str,
        amount: Decimal,
        currency: str,
        subject: str,
        description: str = None,
        user_id: int = None,
        payment_method: PaymentMethod = PaymentMethod.H5,
        return_url: str = None,
        notify_url: str = None,
        extra_params: Dict[str, Any] = None
    ):
        self.order_id = order_id
        self.amount = amount
        self.currency = currency
        self.subject = subject
        self.description = description
        self.user_id = user_id
        self.payment_method = payment_method
        self.return_url = return_url
        self.notify_url = notify_url
        self.extra_params = extra_params or {}

class PaymentResponse:
    """支付响应"""
    def __init__(
        self,
        success: bool,
        order_id: str = None,
        payment_url: str = None,
        qr_code: str = None,
        payment_data: Dict[str, Any] = None,
        error_message: str = None,
        provider_order_id: str = None
    ):
        self.success = success
        self.order_id = order_id
        self.payment_url = payment_url
        self.qr_code = qr_code
        self.payment_data = payment_data or {}
        self.error_message = error_message
        self.provider_order_id = provider_order_id

class PaymentNotification:
    """支付通知"""
    def __init__(
        self,
        order_id: str,
        provider_order_id: str,
        status: OrderStatus,
        amount: Decimal,
        currency: str,
        transaction_id: str = None,
        raw_data: Dict[str, Any] = None
    ):
        self.order_id = order_id
        self.provider_order_id = provider_order_id
        self.status = status
        self.amount = amount
        self.currency = currency
        self.transaction_id = transaction_id
        self.raw_data = raw_data or {}

class BasePaymentService(ABC):
    """支付服务抽象基类"""
    
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.provider = self.get_provider_name()
    
    @abstractmethod
    def get_provider_name(self) -> PaymentProvider:
        """获取支付提供商名称"""
        pass
    
    @abstractmethod
    async def create_payment(self, request: PaymentRequest) -> PaymentResponse:
        """创建支付订单"""
        pass
    
    @abstractmethod
    async def query_payment(self, order_id: str) -> Optional[PaymentNotification]:
        """查询支付状态"""
        pass
    
    @abstractmethod
    async def handle_notification(self, raw_data: Dict[str, Any]) -> Optional[PaymentNotification]:
        """处理支付通知"""
        pass
    
    @abstractmethod
    async def refund_payment(self, order_id: str, amount: Decimal, reason: str = None) -> bool:
        """退款"""
        pass
    
    @abstractmethod
    def verify_signature(self, data: Dict[str, Any], signature: str) -> bool:
        """验证签名"""
        pass
    
    def get_supported_methods(self) -> list[PaymentMethod]:
        """获取支持的支付方式"""
        return [PaymentMethod.H5, PaymentMethod.NATIVE]